package com.kyivmohyla.kma2.client.presenter.operator;

import com.google.gwt.cell.client.NumberCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.kyivmohyla.kma2.client.UserService;
import com.kyivmohyla.kma2.client.events.operator.OperatorEditOrderEvent;
import com.kyivmohyla.kma2.client.events.operator.OperatorImportEvent;
import com.kyivmohyla.kma2.client.events.operator.OperatorNewOrderEvent;
import com.kyivmohyla.kma2.client.gin.Injector;
import com.kyivmohyla.kma2.client.presenter.Presenter;
import com.kyivmohyla.kma2.client.utils.Dialog;
import com.kyivmohyla.kma2.client.view.common.OrderCellTableWidget;
import com.kyivmohyla.kma2.shared.model.UIImportOrder;
import com.kyivmohyla.kma2.shared.model.UIOrder;
import com.kyivmohyla.kma2.shared.model.UIStaff;

import java.util.List;

public class OperatorMainViewPresenter implements Presenter {

    private final static DateTimeFormat dateFormat = DateTimeFormat.getFormat("dd.MM.yyyy");
    private final static DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("dd.MM.yyyy HH:mm");
    private final Display display;
    private final Injector injector = Injector.INSTANCE;
    private UIOrder selectedOrder;
    private CellTable<UIOrder> orderCellTable;
    private SingleSelectionModel<UIOrder> selectionModel;

    public OperatorMainViewPresenter(UIStaff operator) {
        this.display = injector.getOperatorMainView();
        this.orderCellTable = ((CellTable) this.display.getOrderCellTable().getOrderCellTable());
        createTableStructure();
        bind();
        UserService.App.getInstance().getOrdersByState(new int[]{1, 4}, new AsyncCallback<List<UIOrder>>() {
            @Override
            public void onFailure(Throwable throwable) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
            }

            @Override
            public void onSuccess(List<UIOrder> uiOrders) {
                ListDataProvider<UIOrder> dataProvider = new ListDataProvider<UIOrder>(uiOrders);
                dataProvider.addDataDisplay(display.getOrderCellTable().getOrderCellTable());
            }
        });
    }

    public void createTableStructure() {
        selectionModel = new SingleSelectionModel<UIOrder>();
        selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
            public void onSelectionChange(SelectionChangeEvent event) {
                selectedOrder = (UIOrder) ((SingleSelectionModel) event.getSource()).getSelectedObject();
            }
        });
        orderCellTable.setSelectionModel(selectionModel);
        orderCellTable.addDomHandler(new DoubleClickHandler() {
            @Override
            public void onDoubleClick(DoubleClickEvent event) {
                selectedOrder = selectionModel.getSelectedObject();
                if (selectedOrder != null) {
                    injector.getEventBus().fireEvent(new OperatorEditOrderEvent(selectedOrder));
                }
            }
        }, DoubleClickEvent.getType());

        orderCellTable.addColumn(new Column<UIOrder, Number>(new NumberCell()) {
            @Override
            public Number getValue(UIOrder object) {
                return object.getOrderId();
            }
        }, "Order ID");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                return object.getStateName();
            }
        }, "State");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                if (object.getCreateDate() != null)
                    return dateFormat.format(object.getCreateDate());
                return "#######";
            }
        }, "Creation Date");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                return object.getCustomerName();
            }
        }, "Customer");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                if (object.getDesStartDate() != null)
                    return dateTimeFormat.format(object.getDesStartDate());
                return "#######";
            }
        }, "Desirable Start");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                if (object.getDesEndDate() != null)
                    return dateTimeFormat.format(object.getDesEndDate());
                return "#######";
            }
        }, "Desirable End");
        orderCellTable.addColumn(new Column<UIOrder, String>(new TextCell()) {
            @Override
            public String getValue(UIOrder object) {
                return object.getCommentary();
            }
        }, "Commentary");
    }

    private void bind() {
        this.display.getImportOrdersButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                doImportOrder();
            }
        });
        this.display.getNewOrderButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                doOpenNewOrderWindow();
            }
        });
    }

    private void doImportOrder() {
        final DialogBox dialogBox = new DialogBox();
        dialogBox.addStyleName("gwt-DialogBox");
        dialogBox.setText("Import order");
        VerticalPanel dialogContents = new VerticalPanel();
        dialogContents.addStyleName("dialogContents");
        dialogContents.setSpacing(4);
        dialogBox.setWidget(dialogContents);
        final FileUploadPresenter fileUploadPresenter = new FileUploadPresenter();
        dialogContents.add(fileUploadPresenter.getDisplay().asWidget());
        fileUploadPresenter.getDisplay().getFormPanel().addSubmitHandler(new FormPanel.SubmitHandler() {
            @Override
            public void onSubmit(FormPanel.SubmitEvent submitEvent) {
                String fileName = fileUploadPresenter.getDisplay().getFileUpload().getFilename();
                if (fileName.length() == 0) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", "No file is selected. Please select a file to be uploaded.");
                    submitEvent.cancel();
                } else if (!fileName.endsWith("xml")) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", "File format not supported. Only supports XML");
                    submitEvent.cancel();
                }
            }
        });
        fileUploadPresenter.getDisplay().getFormPanel().addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
            @Override
            public void onSubmitComplete(FormPanel.SubmitCompleteEvent submitCompleteEvent) {
                UIImportOrder importOrder = new UIImportOrder();
                JSONValue value = JSONParser.parseStrict(submitCompleteEvent.getResults());
                JSONObject object = value.isObject();
                DateTimeFormat format = DateTimeFormat.getFormat("dd.MM.yyyy HH:mm");
                importOrder.setCustomerName(object.get("customerName").isString().stringValue());
                importOrder.setCustomerPhone(object.get("customerPhone").isString().stringValue());
                importOrder.setCustomerAddress(object.get("customerAddress").isString().stringValue());
                importOrder.setCustomerEmail(object.get("customerEmail").isString().stringValue());
                importOrder.setDesirableStart(format.parse(object.get("desirableStart").isString().stringValue()));
                importOrder.setDesirableEnd(format.parse(object.get("desirableEnd").isString().stringValue()));
                importOrder.setCommentary(object.get("commentary").isString().stringValue());
                injector.getEventBus().fireEvent(new OperatorImportEvent(importOrder));
            }
        });
        fileUploadPresenter.getDisplay().getCancelButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                dialogBox.hide();
            }
        });
        dialogBox.setGlassEnabled(true);
        dialogBox.setAnimationEnabled(true);
        dialogBox.center();
        dialogBox.show();
    }

    private void doOpenNewOrderWindow() {
        injector.getEventBus().fireEvent(new OperatorNewOrderEvent());
    }

    @Override
    public void go(HasWidgets container) {
        container.clear();
        container.add(display.asWidget());
    }

    public interface Display {

        HasClickHandlers getNewOrderButton();

        HasClickHandlers getImportOrdersButton();

        OrderCellTableWidget getOrderCellTable();

        Widget asWidget();
    }
}
